home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / main.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  26KB  |  1,250 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3.  
  4. #define HOSTNAMELEN 64
  5. unsigned restricted_dev=1000;
  6. extern char *startup;    /* File to read startup commands from */
  7. #include <stdio.h>
  8. #include "config.h"
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "netuser.h"
  12. #include "timer.h"
  13. #include "icmp.h"
  14. #include "iface.h"
  15. #include "ip.h"
  16. #include "tcp.h"
  17. #include "ax25.h"
  18. #include "netrom.h"
  19. #include "ftp.h"
  20. #include "telnet.h"
  21. #include "remote.h"
  22. #include "session.h"
  23. #include "cmdparse.h"
  24.  
  25. #ifdef    ASY
  26. #include "asy.h"
  27. #include "slip.h"
  28. #endif
  29.  
  30. #ifdef    NRS
  31. #include "nrs.h"
  32. #endif
  33.  
  34. #ifdef    SLFP
  35. #include "slfp.h"
  36. #endif
  37.  
  38. #ifdef UNIX        /* BSD or SYS5 */
  39. #include "unix.h"
  40. #include <memory.h>
  41. #include <string.h>
  42. #include <sys/types.h>
  43. time_t time();
  44. #endif
  45.  
  46. #ifdef AMIGA
  47. #include "amiga.h"
  48. #endif
  49.  
  50. #ifdef MAC
  51. #include "mac.h"
  52. #endif
  53.  
  54. #ifdef MSDOS
  55. #include "asy.h"
  56. #endif
  57.  
  58. #ifdef    ATARI_ST
  59. #include "st.h"
  60.  
  61. #ifdef    LATTICE
  62. long _MNEED = 100000L;        /* Reserve RAM for subshell... */
  63. long _32K = 0x8000;        /* For GST Linker (Don't ask me! -- hyc) */
  64. #endif
  65.  
  66. #ifdef    MWC
  67. long    _stksize = 16384L;    /* Fixed stack size... -- hyc */
  68. #endif
  69. #endif    /* ATARI_ST */
  70.  
  71. #ifdef    SYS5
  72. #include <signal.h>
  73. int    background = 0;
  74. #endif
  75.  
  76. #ifdef    TRACE
  77. #include "trace.h"
  78. /* Dummy structure for loopback tracing */
  79. struct interface loopback = { NULLIF, "loopback" };
  80. #endif
  81.  
  82. extern struct interface *ifaces;
  83. extern char version[];
  84. extern struct mbuf *loopq;
  85. extern FILE *trfp;
  86. extern char trname[];
  87.  
  88. int mode;
  89. FILE *logfp;
  90. char badhost[] = "Unknown host %s\n";
  91. char hostname[HOSTNAMELEN];    
  92. unsigned nsessions = NSESSIONS;
  93. int32 resolve();
  94. int16 lport = 1001;
  95. char prompt[] = "net> ";
  96. char nospace[] = "No space!!\n";    /* Generic malloc fail message */
  97. #ifdef    SYS5
  98. int io_active = 0;
  99. void daemon();
  100. #endif
  101.  
  102. #if ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))    /* PC/ST uses F-10 key always */
  103. static char escape = 0x1d;    /* default escape character is ^] */
  104. #endif
  105.  
  106. /* Command lookup and branch table */
  107. int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
  108.     dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
  109.     doroute(),doecho(),dolog(),doip(),
  110.     memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
  111.     dosmtp(),doudp(),doparam(),doeol(),
  112.     dodump(),dorecord(),doupload(),dokick(),domode(),doshell(),
  113.     dodir(),docd(),doatstat(),doping(),doforward(),doremote(),donetrom(),
  114.     donrstat(), dombox(), mulport() ;
  115.  
  116. #ifdef ETHER
  117. int doetherstat();
  118. #endif
  119. #ifdef EAGLE
  120. int doegstat();
  121. #endif
  122. #ifdef HAPN
  123. int dohapnstat();
  124. #endif
  125. #ifdef _FINGER
  126. int dofinger();
  127. #endif
  128.  
  129. static struct cmds cmds[] = {
  130.     /* The "go" command must be first */
  131.     "",        go,        0, NULLCHAR,    NULLCHAR,
  132.     "!",        doshell,    0, NULLCHAR,    NULLCHAR,
  133. #if    (MAC && APPLETALK)
  134.     "applestat",    doatstat,    0,    NULLCHAR,    NULLCHAR,
  135. #endif
  136. #if    (AX25 || ETHER || APPLETALK)
  137.     "arp",        doarp,        0, NULLCHAR,    NULLCHAR,
  138. #endif
  139. #ifdef    AX25
  140.     "ax25",        doax25,        0, NULLCHAR,    NULLCHAR,
  141. #endif    
  142.     "attach",    doattach,    2,
  143.         "attach <hardware> <hw specific options>", NULLCHAR,
  144. /* This one is out of alpabetical order to allow abbreviation to "c" */
  145. #ifdef    AX25
  146.     "connect",    doconnect,    3,"connect <interface> <callsign> [digipeaters]",
  147.         NULLCHAR,
  148. #endif
  149.     "cd",        docd,        0, NULLCHAR,    NULLCHAR,
  150.     "close",    doclose,    0, NULLCHAR,    NULLCHAR,
  151.     "disconnect",    doclose,    0, NULLCHAR,    NULLCHAR,
  152.     "dir",        dodir,        0, NULLCHAR,    NULLCHAR,
  153. #ifdef    EAGLE
  154.     "eaglestat",    doegstat,    0, NULLCHAR,    NULLCHAR,
  155. #endif
  156.     "echo",        doecho,        0, NULLCHAR,    "echo [refuse|accept]",
  157.     "eol",        doeol,        0, NULLCHAR,
  158.         "eol options: unix, standard",
  159. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  160.     "escape",    doescape,    0, NULLCHAR,    NULLCHAR,   
  161. #endif
  162. #ifdef    PC_EC
  163.     "etherstat",    doetherstat,    0, NULLCHAR,    NULLCHAR,
  164. #endif  PC_EC
  165.     "exit",        doexit,        0, NULLCHAR,    NULLCHAR,
  166. #ifdef _FINGER
  167.     "finger",    dofinger,    0, NULLCHAR, NULLCHAR,
  168. #endif
  169.     "forward",    doforward,    0, NULLCHAR,    NULLCHAR,
  170.     "ftp",        doftp,        2, "ftp <address>",    NULLCHAR,
  171. #ifdef HAPN
  172.     "hapnstat",    dohapnstat,    0, NULLCHAR,    NULLCHAR,
  173. #endif
  174.     "help",        dohelp,        0, NULLCHAR,    NULLCHAR,
  175.     "hostname",    dohostname,    0, NULLCHAR,    NULLCHAR,
  176.     "kick",        dokick,        0, NULLCHAR,    NULLCHAR,
  177.     "log",        dolog,        0, NULLCHAR,    NULLCHAR,
  178.     "ip",        doip,        0, NULLCHAR,    NULLCHAR,
  179.     "memstat",    memstat,    0, NULLCHAR,    NULLCHAR,
  180. #ifdef    AX25
  181.     "mbox",        dombox,        0, NULLCHAR,    NULLCHAR,
  182.     "mode",        domode,        2, "mode <interface>",    NULLCHAR,
  183. #endif
  184. #ifdef    MULPORT
  185.     "mulport",    mulport,    2, "mulport <on|off>",    NULLCHAR,
  186. #endif
  187. #ifdef    NETROM
  188.     "netrom",    donetrom,    0, NULLCHAR,    NULLCHAR,
  189. #ifdef    NRS
  190.     "nrstat",    donrstat,    0, NULLCHAR,    NULLCHAR,
  191. #endif
  192. #endif
  193.     "param",    doparam,    2, "param <interface>", NULLCHAR,
  194.     "ping",        doping,        0, NULLCHAR,    NULLCHAR,
  195.     "pwd",        docd,        0, NULLCHAR,    NULLCHAR,
  196.     "record",    dorecord,    0, NULLCHAR,    NULLCHAR,
  197.     "remote",    doremote,    4, "remote <address> <port> <command>",
  198.                             NULLCHAR,
  199.     "reset",    doreset,    0, NULLCHAR,    NULLCHAR,
  200.     "route",    doroute,    0, NULLCHAR,    NULLCHAR,
  201.     "session",    dosession,    0, NULLCHAR,    NULLCHAR,
  202.     "shell",    doshell,    0, NULLCHAR,    NULLCHAR,
  203.     "smtp",        dosmtp,        0, NULLCHAR,    NULLCHAR,
  204. #ifdef    SERVERS
  205.     "start",    dostart,    2, "start <servername>",NULLCHAR,
  206.     "stop",        dostop,        2, "stop <servername>",    NULLCHAR,
  207. #endif
  208.     "tcp",        dotcp,        0, NULLCHAR,    NULLCHAR,
  209.     "telnet",    dotelnet,    2, "telnet <address>",    NULLCHAR,
  210. #ifdef    TRACE
  211.     "trace",    dotrace,    0, NULLCHAR,    NULLCHAR,
  212. #endif
  213.     "udp",        doudp,        0, NULLCHAR,    NULLCHAR,
  214.     "upload",    doupload,    0, NULLCHAR,    NULLCHAR,
  215.     "?",        dohelp,        0, NULLCHAR,    NULLCHAR,
  216.     NULLCHAR,    NULLFP,        0,
  217.         "Unknown command; type \"?\" for list",   NULLCHAR, 
  218. };
  219.  
  220. #ifdef    SERVERS
  221. /* "start" and "stop" subcommands */
  222. int dis1(),echo1(),ftp1(),smtp1(),tn1(),rem1();
  223.  
  224. #ifdef UNIX
  225. int tnix1();
  226. #endif
  227.  
  228. #ifdef _FINGER
  229. int finger1();
  230. #endif
  231.  
  232. static struct cmds startcmds[] = {
  233.     "discard",    dis1,        0, NULLCHAR, NULLCHAR,
  234.     "echo",        echo1,        0, NULLCHAR, NULLCHAR,
  235. #ifdef _FINGER
  236.     "finger",    finger1,    0, NULLCHAR, NULLCHAR,
  237. #endif
  238.     "ftp",        ftp1,        0, NULLCHAR, NULLCHAR,
  239.     "smtp",        smtp1,        0, NULLCHAR, NULLCHAR,
  240.     "telnet",    tn1,        0, NULLCHAR, NULLCHAR,
  241. #ifdef    UNIX
  242.     "telunix",    tnix1,        0, NULLCHAR, NULLCHAR,
  243. #endif
  244.     "remote",    rem1,        0, NULLCHAR, NULLCHAR,
  245.     NULLCHAR,    NULLFP,        0,
  246. #ifdef UNIX
  247. #ifdef _FINGER
  248.         "start options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  249. #else
  250.         "start options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  251. #endif
  252. #else /* UNIX */
  253. #ifdef _FINGER
  254.         "start options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  255. #else
  256.         "start options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  257. #endif
  258. #endif /* UNIX */
  259. };
  260. int ftp_stop(),smtp_stop(),echo_stop(),dis_stop(),tn_stop();
  261. int dis0(),echo0(),ftp0(),smtp0(),tn0(),rem0();
  262.  
  263. #ifdef UNIX
  264. int tnix0();
  265. #endif
  266.  
  267. #ifdef _FINGER
  268. int finger0();
  269. #endif
  270.  
  271. static struct cmds stopcmds[] = {
  272.     "discard",    dis0,        0, NULLCHAR, NULLCHAR,
  273.     "echo",        echo0,        0, NULLCHAR, NULLCHAR,
  274. #ifdef _FINGER
  275.     "finger",    finger0,    0, NULLCHAR, NULLCHAR,
  276. #endif
  277.     "ftp",        ftp0,        0, NULLCHAR, NULLCHAR,
  278.     "smtp",        smtp0,        0, NULLCHAR, NULLCHAR,
  279.     "telnet",    tn0,        0, NULLCHAR, NULLCHAR,
  280. #ifdef UNIX
  281.     "telunix",    tnix0,        0, NULLCHAR, NULLCHAR,
  282. #endif
  283.     "remote",    rem0,        0, NULLCHAR, NULLCHAR,
  284.     NULLCHAR,    NULLFP,        0,
  285. #ifdef UNIX
  286. #ifdef _FINGER
  287.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  288. #else
  289.         "stop options: discard, echo, ftp, remote, smtp, telnet, telunix", NULLCHAR,
  290. #endif
  291. #else /* UNIX */
  292. #ifdef _FINGER
  293.         "stop options: discard, echo, finger, ftp, remote, smtp, telnet", NULLCHAR,
  294. #else
  295.         "stop options: discard, echo, ftp, remote, smtp, telnet", NULLCHAR,
  296. #endif
  297. #endif /* UNIX */
  298. };
  299. #endif
  300.  
  301. void
  302. keep_things_going()
  303. {
  304.     void check_time(), ip_recv();
  305.     struct interface *ifp;
  306.     struct mbuf *bp;
  307.  
  308.     /* Service the loopback queue */
  309.     if((bp = dequeue(&loopq)) != NULLBUF){
  310.         struct ip ip;
  311. #ifdef    TRACE
  312.         dump(&loopback,IF_TRACE_IN,TRACE_IP,bp);        
  313. #endif
  314.         /* Extract IP header */
  315.         ntohip(&ip,&bp);
  316.         ip_recv(&ip,bp,0);
  317.     }
  318.     /* Service the interfaces */
  319. #ifdef    SYS5
  320.     do {
  321.     io_active = 0;
  322. #endif
  323.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next){
  324.         if(ifp->recv != NULLVFP)
  325.             (*ifp->recv)(ifp);
  326.     }
  327. #ifdef    SYS5
  328.     } while(io_active);
  329. #endif
  330.  
  331. #ifdef    XOBBS
  332.     /* service the W2XO PBBS code */
  333.     axchk();
  334. #endif
  335.  
  336.  
  337.  
  338.     /* Service the clock if it has ticked */
  339.     check_time();
  340.  
  341. #ifdef    MSDOS
  342.     /* Tell DoubleDos to let the other task run for awhile.
  343.      * If DoubleDos isn't active, this is a no-op
  344.      */
  345. #ifndef PLUS
  346.     giveup();
  347. #endif
  348. #else
  349.     /* Wait until interrupt, then do it all over again */
  350.     eihalt();
  351. #endif
  352. }
  353.  
  354. main(argc,argv)
  355. int argc;
  356. char *argv[];
  357. {
  358.     static char inbuf[BUFSIZ];    /* keep it off the stack */
  359.     int c;
  360.     char *ttybuf,*fgets();
  361.     int16 cnt;
  362.     int ttydriv();
  363.     int cmdparse();
  364.     void check_time(),ip_recv();
  365.     FILE *fp;
  366. #ifdef    FLOW
  367.     extern int ttyflow;
  368. #endif
  369.  
  370. #ifdef    UNIX
  371.     fileinit(argv[0]);
  372. #endif
  373. #ifdef    SYS5
  374.     if (signal(SIGINT, SIG_IGN) == SIG_IGN) {
  375.         background++;
  376.         daemon();
  377.     } else
  378.         ioinit();
  379. #else
  380.     ioinit();
  381. #endif
  382.  
  383. #ifdef PLUS
  384. /*
  385.  * set: cursor to block, attributes off, keyboard to ALT mode, 
  386.  *      transmit functions off, use HP fonts
  387.  */
  388.     printf(   "\033&d@"     /* display attributes off         */
  389.                   "\033[11m");  /* use ALT fonts                  */
  390. #endif
  391. #ifdef    MSDOS
  392. #ifndef PLUS
  393.     chktasker();
  394. #endif
  395. #endif
  396. #ifdef    MSDOS
  397.     printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
  398.         getds());
  399. #else
  400. #ifdef    SYS5
  401.     if (!background) {
  402. #endif
  403.         printf("KA9Q Internet Protocol Package, v%s\n",version);
  404. #endif
  405.         printf("Copyright 1988 by Phil Karn, KA9Q\n");
  406. #ifdef NETROM
  407.         printf("NET/ROM Support Copyright 1989 by Dan Frank, W9NK\n") ;
  408. #endif
  409. #ifdef    SYS5
  410.     }
  411. #endif
  412.     fflush(stdout);
  413.     sessions = (struct session *)calloc(nsessions,sizeof(struct session));
  414.     if(argc > 1){
  415.         /* Read startup file named on command line */
  416.         fp = fopen(argv[1],"r");
  417.     } else {
  418.         fp = fopen(startup,"r");
  419.     }
  420.     if(fp != NULLFILE){
  421.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  422.             cmdparse(cmds,inbuf);
  423.         }
  424.         fclose(fp);
  425.     }        
  426. #ifdef XOBBS
  427.     axinit();
  428. #endif
  429.     cmdmode();
  430.  
  431.     /* Main commutator loop */
  432.     for(;;){
  433.         /* Process any keyboard input */
  434. #ifdef    SYS5
  435.         while((background == 0) && ((c = kbread()) != -1)){
  436. #else
  437.         while((c = kbread()) != -1){
  438. #endif
  439. #if    (defined(MSDOS) || defined(ATARI_ST))
  440.             /* c == -2 means the command escape key (F10) */
  441.             if(c == -2){
  442.                 if(mode != CMD_MODE){
  443.                     printf("\n");
  444.                     cmdmode();
  445.                 }
  446.                 continue;
  447.             }
  448. #endif
  449. #ifdef SYS5
  450.             if(c == escape && escape != 0){
  451.                 if(mode != CMD_MODE){
  452.                     printf("\r\n");
  453.                     cmdmode();
  454.                 }
  455.                 continue;
  456.             }
  457. #endif     /* SYS5 */
  458.  
  459. #ifndef    FLOW
  460.             if ((cnt = ttydriv(c, &ttybuf)) == 0)
  461.                 continue;
  462. #else
  463.             cnt = ttydriv(c, &ttybuf);
  464.             if (ttyflow && (mode != CMD_MODE))
  465.                 go();        /* display pending chars */
  466.             if (cnt == 0)
  467.                 continue;
  468. #endif    /* FLOW */
  469. #if    (!defined(MSDOS) && !defined(ATARI_ST))
  470.             if((ttybuf[0] == escape) && (escape != 0)) {
  471.                 if(mode != CMD_MODE){
  472.                     printf("\r\n");
  473.                     cmdmode();
  474.                 }
  475.                 continue;
  476.             }
  477. #endif
  478.             switch(mode){
  479.             case CMD_MODE:
  480.                 (void)cmdparse(cmds,ttybuf);
  481.                 fflush(stdout);
  482.                 break;
  483.             case CONV_MODE:
  484. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  485.                 if(ttybuf[0] == escape && escape != 0){
  486.                     printf("\n");
  487.                     cmdmode();
  488.                 } else
  489. #endif    /* MSDOS */
  490.                     if(current->parse != NULLFP)
  491.                         (*current->parse)(ttybuf,cnt);
  492.                 break;
  493.             }
  494.             if(mode == CMD_MODE){
  495.                 printf(prompt);
  496.                 fflush(stdout);
  497.             }
  498.         }
  499.         keep_things_going();
  500.     }
  501. }
  502. /* Standard commands called from main */
  503.  
  504. /* Enter command mode */
  505. int
  506. cmdmode()
  507. {
  508.     if(mode != CMD_MODE){
  509.         mode = CMD_MODE;
  510.         cooked();
  511.         printf(prompt);
  512.         fflush(stdout);
  513.     }
  514.     return 0;
  515. }
  516. static
  517. doexit()
  518. {
  519.     void iostop();
  520.  
  521. #if    defined(PLUS)
  522. /*
  523.  * set: cursor to block, attributes off, keyboard to HP mode,
  524.  *      transmit functions off, use HP fonts
  525.  */
  526.     printf(/* "\033*dK"       cursor to block        */
  527.               "\033&d@"    /* display attributes off      */
  528.            /* "\033&k0\\"       KBD to HP mode        */
  529.            /* "\033&s0A"       transmit functions off    */
  530.               "\033[10m");    /* use HP fonts            */
  531. #endif
  532.     if(logfp != NULLFILE)
  533.         fclose(logfp);
  534. #ifdef    SYS5
  535.     if (!background)
  536.         iostop();
  537. #else
  538.     iostop();
  539. #endif
  540. #ifdef TRACE
  541.     if (trfp != stdout) 
  542.       fclose(trfp);
  543. #endif
  544.     exit(0);
  545. }
  546. static
  547. dohostname(argc,argv)
  548. int argc;
  549. char *argv[];
  550. {
  551.     char *strncpy();
  552.  
  553.     if(argc < 2)
  554.         printf("%s\n",hostname);
  555.     else 
  556.         strncpy(hostname,argv[1],HOSTNAMELEN);
  557.     return 0;
  558. }
  559. static
  560. int
  561. dolog(argc,argv)
  562. int argc;
  563. char *argv[];
  564. {
  565.     char *strncpy();
  566.  
  567. #ifdef    UNIX
  568.     static char logname[256];
  569. #else
  570.     static char logname[15];
  571. #endif
  572.     if(argc < 2){
  573.         if(logfp)
  574.             printf("Logging to %s\n",logname);
  575.         else
  576.             printf("Logging off\n");
  577.         return 0;
  578.     }
  579.     if(logfp){
  580.         fclose(logfp);
  581.         logfp = NULLFILE;
  582.     }
  583.     if(strcmp(argv[1],"stop") != 0){
  584. #ifdef    UNIX
  585.         strncpy(logname,argv[1],sizeof(logname));
  586. #else
  587.         strncpy(logname,argv[1],15);
  588. #endif
  589.         logfp = fopen(logname,"a+");
  590.     }
  591.     return 0;
  592. }
  593. static
  594. int
  595. dohelp()
  596. {
  597.     register struct cmds *cmdp;
  598.     int i,j;
  599.  
  600.     printf("Main commands:\n");
  601.     for(i=0,cmdp = cmds;cmdp->name != NULL;cmdp++,i++){
  602.         printf("%s",cmdp->name);
  603.         if((i % 4) == 3)
  604.             printf("\n");
  605.         else {
  606.             for(j=strlen(cmdp->name);j < 16; j++)
  607.                 putchar(' ');
  608.         }
  609.     }
  610.     if((i % 4) != 0)
  611.         printf("\n");
  612.     return 0;
  613. }
  614.  
  615. doecho(argc,argv)
  616. int argc;
  617. char *argv[];
  618. {
  619.     extern int refuse_echo;
  620.  
  621.     if(argc < 2){
  622.         if(refuse_echo)
  623.             printf("Refuse\n");
  624.         else
  625.             printf("Accept\n");
  626.     } else {
  627.         if(argv[1][0] == 'r')
  628.             refuse_echo = 1;
  629.         else if(argv[1][0] == 'a')
  630.             refuse_echo = 0;
  631.         else
  632.             return -1;
  633.     }
  634.     return 0;
  635. }
  636. /* set for unix end of line for remote echo mode telnet */
  637. doeol(argc,argv)
  638. int argc;
  639. char *argv[];
  640. {
  641.     extern int unix_line_mode;
  642.  
  643.     if(argc < 2){
  644.         if(unix_line_mode)
  645.             printf("Unix\n");
  646.         else
  647.             printf("Standard\n");
  648.     } else {
  649.         if(strcmp(argv[1],"unix") == 0)
  650.             unix_line_mode = 1;
  651.         else if(strcmp(argv[1],"standard") == 0)
  652.             unix_line_mode = 0;
  653.         else {
  654.             return -1;
  655.         }
  656.     }
  657.     return 0;
  658. }
  659. /* Attach an interface
  660.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  661.  */
  662. doattach(argc,argv)
  663. int argc;
  664. char *argv[];
  665. {
  666.     extern struct cmds attab[];
  667.  
  668.     return subcmd(attab,argc,argv);
  669. }
  670. /* Manipulate I/O device parameters */
  671. doparam(argc,argv)
  672. int argc;
  673. char *argv[];
  674. {
  675.     register struct interface *ifp;
  676.  
  677.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  678.         if(strcmp(argv[1],ifp->name) == 0)
  679.             break;
  680.     }
  681.     if(ifp == NULLIF){
  682.         printf("Interface \"%s\" unknown\n",argv[1]);
  683.         return 1;
  684.     }
  685.     if(ifp->ioctl == NULLFP){
  686.         printf("Not supported\n");
  687.         return 1;
  688.     }
  689.     /* Pass rest of args to device-specific code */
  690.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  691. }
  692. /* Log messages of the form
  693.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  694.  */
  695. /*VARARGS2*/
  696. log(tcb,fmt,arg1,arg2,arg3,arg4)
  697. struct tcb *tcb;
  698. char *fmt;
  699. int32 arg1,arg2,arg3,arg4;
  700. {
  701.     char *cp;
  702.     long t;
  703. #if    (defined(MSDOS) || defined(ATARI_ST))
  704.     int fd;
  705. #endif
  706.  
  707.     if(logfp == NULLFILE)
  708.         return;
  709.     time(&t);
  710.     cp = ctime(&t);
  711.     rip(cp);
  712.     if (tcb)
  713.         fprintf(logfp,"%s %s - ",cp,psocket(&tcb->conn.remote));
  714.     else
  715.         fprintf(logfp,"%s - ",cp);
  716.     fprintf(logfp,fmt,arg1,arg2,arg3,arg4);
  717.     fprintf(logfp,"\n");
  718.     fflush(logfp);
  719. #if    (defined(MSDOS) || defined(ATARI_ST))
  720.     /* MS-DOS doesn't really flush files until they're closed */
  721.     fd = fileno(logfp);
  722.     if((fd = dup(fd)) != -1)
  723.         close(fd);
  724. #endif
  725. }
  726. /* Configuration-dependent code */
  727.  
  728. /* List of supported hardware devices */
  729. int modem_init(),asy_attach(),pc_attach(),at_attach(),nr_attach();
  730.  
  731. #ifdef    EAGLE
  732. int eg_attach();
  733. #endif
  734. #ifdef    HAPN
  735. int hapn_attach();
  736. #endif
  737. #ifdef    PC_EC
  738. int ec_attach();
  739. #endif
  740. #ifdef    PACKET
  741. int pk_attach();
  742. #endif
  743.  
  744. struct cmds attab[] = {
  745. #ifdef    PC_EC
  746.     /* 3-Com Ethernet interface */
  747.     "3c500", ec_attach, 7, 
  748.     "attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
  749.     "Could not attach 3c500",
  750. #endif
  751. #ifdef    ASY
  752.     /* Ordinary PC asynchronous adaptor */
  753.     "asy", asy_attach, 8, 
  754. #ifdef    UNIX
  755. #ifndef    SLFP
  756.     "attach asy 0 <ttyname> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  757. #else
  758.     "attach asy 0 <ttyname> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  759. #endif    /* SLFP */
  760. #else
  761. #ifndef    SLFP
  762.     "attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  763. #else
  764.     "attach asy <address> <vector> slip|ax25|nrs|slfp <label> <buffers> <mtu> <speed>",
  765. #endif    /* SLFP */
  766. #endif
  767.     "Could not attach asy",
  768. #endif
  769. #ifdef    PC100
  770.     /* PACCOMM PC-100 8530 HDLC adaptor */
  771.     "pc100", pc_attach, 8, 
  772.     "attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  773.     "Could not attach pc100",
  774. #endif
  775. #ifdef    EAGLE
  776.     /* EAGLE RS-232C 8530 HDLC adaptor */
  777.     "eagle", eg_attach, 8,
  778.     "attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  779.     "Could not attach eagle",
  780. #endif
  781. #ifdef    HAPN
  782.     /* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
  783.     "hapn", hapn_attach, 8,
  784.     "attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
  785.     "Could not attach hapn",
  786. #endif
  787. #ifdef    APPLETALK
  788.     /* Macintosh AppleTalk */
  789.     "0", at_attach, 7,
  790.     "attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
  791.     "Could not attach Appletalk",
  792. #endif
  793. #ifdef NETROM
  794.     /* fake netrom interface */
  795.     "netrom", nr_attach, 1,
  796.     "attach netrom",
  797.     "Could not attach netrom",
  798. #endif
  799. #ifdef    PACKET
  800.     /* FTP Software's packet driver spec */
  801.     "packet", pk_attach, 4,
  802.     "attach packet <int#> <label> <buffers> <mtu>",
  803.     "Could not attach packet driver",
  804. #endif
  805.     NULLCHAR, NULLFP, 0,
  806.     "Unknown device",
  807.     NULLCHAR,
  808. };
  809.  
  810. /* Protocol tracing function pointers */
  811. #ifdef    TRACE
  812. int ax25_dump(),ether_dump(),ip_dump(),at_dump(),slfp_dump();
  813.  
  814. int (*tracef[])() = {
  815. #ifdef    AX25
  816.     ax25_dump,
  817. #else
  818.     NULLFP,
  819. #endif
  820.  
  821. #ifdef    ETHER
  822.     ether_dump,
  823. #else
  824.     NULLFP,
  825. #endif
  826.     ip_dump,
  827.  
  828. #ifdef    APPLETALK
  829.     at_dump,
  830. #else
  831.     NULLFP,
  832. #endif
  833.  
  834. #ifdef    SLFP
  835.     slfp_dump,
  836. #else
  837.     NULLFP,
  838. #endif
  839. };
  840. #else
  841. int (*tracef[])() = { NULLFP };    /* No tracing at all */
  842. dump(interface,direction,type,bp)
  843. struct interface *interface;
  844. int direction;
  845. unsigned type;
  846. struct mbuf *bp;
  847. {
  848. }
  849. #endif
  850.  
  851. #ifdef    ASY
  852.  
  853. /* Attach a serial interface to the system
  854.  * argv[0]: hardware type, must be "asy"
  855.  * argv[1]: I/O address, e.g., "0x3f8"
  856.  * argv[2]: vector, e.g., "4"
  857.  * argv[3]: mode, may be:
  858.  *        "slip" (point-to-point SLIP)
  859.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  860.  *        "nrs" (NET/ROM format serial protocol)
  861.  *        "slfp" (point-to-point SLFP, as used by the Merit Network and MIT
  862.  * argv[4]: interface label, e.g., "sl0"
  863.  * argv[5]: receiver ring buffer size in bytes
  864.  * argv[6]: maximum transmission unit, bytes
  865.  * argv[7]: interface speed, e.g, "9600"
  866.  * argv[8]: optional ax.25 callsign (NRS only)
  867.  *        optional command string for modem (SLFP only)
  868.  *          optional modem L.sys style command (SLIP only)
  869.  */
  870. int
  871. asy_attach(argc,argv)
  872. int argc;
  873. char *argv[];
  874. {
  875.     register struct interface *if_asy;
  876.     extern struct interface *ifaces;
  877.     int16 dev;
  878.     int mode;
  879.     int asy_init();
  880.     int asy_send();
  881.     int asy_ioctl();
  882.     void doslip();
  883.     int asy_stop();
  884.     int ax_send();
  885.     int ax_output();
  886.     void kiss_recv();
  887.     int kiss_raw();
  888.     int kiss_ioctl();
  889.     int slip_send();
  890.     void slip_recv();
  891.     int slip_raw();
  892.  
  893. #ifdef    SLFP
  894.     int doslfp();
  895.     int slfp_raw();
  896.     int slfp_send();
  897.     int slfp_recv();
  898.     int slfp_init();
  899. #endif
  900.  
  901. #ifdef    AX25
  902.     struct ax25_addr addr ;
  903. #endif
  904.     int ax_send(),ax_output(),nrs_raw(),asy_ioctl();
  905.     void nrs_recv();
  906.  
  907.     if(nasy >= ASY_MAX){
  908.         printf("Too many asynch controllers\n");
  909.         return -1;
  910.     }
  911.     if(strcmp(argv[3],"slip") == 0)
  912.         mode = SLIP_MODE;
  913. #ifdef    AX25
  914.     else if(strcmp(argv[3],"ax25") == 0)
  915.         mode = AX25_MODE;
  916. #endif
  917. #ifdef    NRS
  918.     else if(strcmp(argv[3],"nrs") == 0)
  919.         mode = NRS_MODE;
  920. #endif
  921. #ifdef    SLFP
  922.     else if(strcmp(argv[3],"slfp") == 0)
  923.         mode = SLFP_MODE;
  924. #endif
  925.     else {
  926.         printf("Mode %s unknown for interface %s\n",
  927.             argv[3],argv[4]);
  928.         return(-1);
  929.     }
  930.  
  931.     dev = nasy++;
  932.  
  933.     /* Create interface structure and fill in details */
  934.     if_asy = (struct interface *)calloc(1,sizeof(struct interface));
  935.     if_asy->name = malloc((unsigned)strlen(argv[4])+1);
  936.     strcpy(if_asy->name,argv[4]);
  937.     if_asy->mtu = atoi(argv[6]);
  938.     if_asy->dev = dev;
  939.     if_asy->recv = doslip;
  940.     if_asy->stop = asy_stop;
  941.  
  942.     switch(mode){
  943. #ifdef    SLIP
  944.     case SLIP_MODE:
  945.         if_asy->ioctl = asy_ioctl;
  946.         if_asy->send = slip_send;
  947.         if_asy->output = NULLFP;    /* ARP isn't used */
  948.         if_asy->raw = slip_raw;
  949.         if_asy->flags = 0;
  950.         slip[dev].recv = slip_recv;
  951.         break;
  952. #endif
  953. #ifdef    AX25
  954.     case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  955.         axarp();
  956.         if(mycall.call[0] == '\0'){
  957.             printf("set mycall first\n");
  958.             free(if_asy->name);
  959.             free((char *)if_asy);
  960.             nasy--;
  961.             return -1;
  962.         }
  963.         if_asy->ioctl = kiss_ioctl;
  964.         if_asy->send = ax_send;
  965.         if_asy->output = ax_output;
  966.         if_asy->raw = kiss_raw;
  967.         if(if_asy->hwaddr == NULLCHAR)
  968.             if_asy->hwaddr = malloc(sizeof(mycall));
  969.         memcpy(if_asy->hwaddr,(char *)&mycall,sizeof(mycall));
  970.         slip[dev].recv = kiss_recv;
  971.         break;
  972. #endif
  973. #ifdef    NRS
  974.     case NRS_MODE: /* Set up a net/rom serial interface */
  975.         if(argc < 9){
  976.             /* no call supplied? */
  977.             if(mycall.call[0] == '\0'){
  978.                 /* try to use default */
  979.                 printf("set mycall first or specify in attach statement\n");
  980.                 return -1;
  981.             } else
  982.                 addr = mycall;
  983.         } else {
  984.             /* callsign supplied on attach line */
  985.             if(setcall(&addr,argv[8]) == -1){
  986.                 printf ("bad callsign on attach line\n");
  987.                 free(if_asy->name);
  988.                 free((char *)if_asy);
  989.                 nasy--;
  990.                 return -1;
  991.             }
  992.         }
  993.         if_asy->recv = nrs_recv;
  994.         if_asy->ioctl = asy_ioctl;
  995.         if_asy->send = ax_send;
  996.         if_asy->output = ax_output;
  997.         if_asy->raw = nrs_raw;
  998.         if(if_asy->hwaddr == NULLCHAR)
  999.             if_asy->hwaddr = malloc(sizeof(addr));
  1000.         memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  1001.         nrs[dev].iface = if_asy;
  1002.         break;
  1003. #endif
  1004. #ifdef    SLFP
  1005.     case SLFP_MODE:
  1006.         if_asy->ioctl = asy_ioctl;
  1007.         if_asy->send = slfp_send;
  1008.         if_asy->recv = doslfp;
  1009.         if_asy->output = NULLFP;    /* ARP isn't used */
  1010.         if_asy->raw = slfp_raw;
  1011.         if_asy->flags = 0;
  1012.         slfp[dev].recv = slfp_recv;
  1013.         break;
  1014. #endif
  1015.     }
  1016.     if_asy->next = ifaces;
  1017.     ifaces = if_asy;
  1018.     asy_init(dev,argv[1],argv[2],(unsigned)atoi(argv[5]));
  1019.     asy_speed(dev,atoi(argv[7]));
  1020. /*
  1021.  * optional SLIP modem command?
  1022.  */
  1023. #if defined(SLIP) && defined(MODEM_CALL)
  1024.     if((mode == SLIP_MODE) && (argc > 8)) {
  1025.         restricted_dev=dev;
  1026.         if((modem_init(dev,argc-8,argv+8)) == -1) {
  1027.         printf("\nModem command sequence failed.\n");
  1028.         asy_stop(if_asy);
  1029.         ifaces = if_asy->next;
  1030.         free(if_asy->name);
  1031.         free((char *)if_asy);
  1032.         nasy--;
  1033.         restricted_dev=1000;
  1034.         return -1;
  1035.         }
  1036.         restricted_dev=1000;
  1037.         return 0;
  1038.     }
  1039. #endif
  1040. #ifdef    SLFP
  1041.     if(mode == SLFP_MODE)
  1042.         if(slfp_init(if_asy, argc>7?argv[8]:NULLCHAR) == -1) {
  1043.         printf("Request for IP address failed.\n");
  1044.         asy_stop(if_asy);
  1045.         ifaces = if_asy->next;
  1046.         free(if_asy->name);
  1047.         free((char *)if_asy);
  1048.         nasy--;
  1049.         return -1;
  1050.         }
  1051. #endif
  1052.     return 0;
  1053. }
  1054. #endif
  1055. #ifndef    NETROM
  1056. #ifdef    AX25
  1057. struct ax25_addr nr_nodebc;
  1058. #endif
  1059. nr_route(bp)
  1060. struct mbuf *bp;
  1061. {
  1062.     free_p(bp);
  1063. }
  1064. nr_nodercv(bp)
  1065. {
  1066.     free_p(bp);
  1067. }
  1068. #endif
  1069.  
  1070.  
  1071. /* Display or set IP interface control flags */
  1072. domode(argc,argv)
  1073. int argc;
  1074. char *argv[];
  1075. {
  1076.     register struct interface *ifp;
  1077.  
  1078.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  1079.         if(strcmp(argv[1],ifp->name) == 0)
  1080.             break;
  1081.     }
  1082.     if(ifp == NULLIF){
  1083.         printf("Interface \"%s\" unknown\n",argv[1]);
  1084.         return 1;
  1085.     }
  1086.     if(argc < 3){
  1087.         printf("%s: %s\n",ifp->name,
  1088.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  1089.         return 0;
  1090.     }
  1091.     switch(argv[2][0]){
  1092.     case 'v':
  1093.     case 'c':
  1094.     case 'V':
  1095.     case 'C':
  1096.         ifp->flags = CONNECT_MODE;
  1097.         break;
  1098.     case 'd':
  1099.     case 'D':
  1100.         ifp->flags = DATAGRAM_MODE;
  1101.         break;
  1102.     default:
  1103.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  1104.         return 1;
  1105.     }
  1106.     return 0;
  1107. }
  1108.  
  1109. #ifdef SERVERS
  1110. dostart(argc,argv)
  1111. int argc;
  1112. char *argv[];
  1113. {
  1114.     return subcmd(startcmds,argc,argv);
  1115. }
  1116. dostop(argc,argv)
  1117. int argc;
  1118. char *argv[];
  1119. {
  1120.     return subcmd(stopcmds,argc,argv);
  1121. }
  1122. #endif SERVERS
  1123.  
  1124. #ifdef    TRACE
  1125. static
  1126. int
  1127. dotrace(argc,argv)
  1128. int argc;
  1129. char *argv[];
  1130. {
  1131.         extern int notraceall;  /* trace only in command mode? */
  1132.     struct interface *ifp;
  1133.  
  1134.     if(argc < 2){
  1135.          printf("trace mode is %s\n", (notraceall ? "cmdmode" : "allmode"));
  1136.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1137.         showtrace(&loopback);
  1138.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1139.             showtrace(ifp);
  1140.         return 0;
  1141.     }
  1142.     if(strcmp("to",argv[1]) == 0){
  1143.         if(argc >= 3){
  1144.             if(trfp != stdout)
  1145.                 fclose(trfp);
  1146.             if(strncmp(argv[2],"con",3) == 0)
  1147.                 trfp = stdout;
  1148.             else {
  1149.                 if((trfp = fopen(argv[2],"a")) == NULLFILE){
  1150.                     printf("%s: cannot open\n",argv[2]);
  1151.                     trfp = stdout;
  1152.                     return 1;
  1153.                 }
  1154.             }
  1155.             strcpy(trname,argv[2]);
  1156.         } else {
  1157.             printf("trace to %s\n",trfp == stdout? "console" : trname);
  1158.         }
  1159.         return 0;
  1160.     }
  1161.     if(strcmp("loopback",argv[1]) == 0)
  1162.         ifp = &loopback;
  1163.      else if (strcmp("cmdmode", argv[1]) == 0) {
  1164.          notraceall = 1;
  1165.          return 0;
  1166.      } else if (strcmp("allmode", argv[1]) == 0) {
  1167.          notraceall = 0;
  1168.          return 0;
  1169.      } else
  1170.         for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  1171.             if(strcmp(ifp->name,argv[1]) == 0)
  1172.                 break;
  1173.  
  1174.     if(ifp == NULLIF){
  1175.         printf("Interface %s unknown\n",argv[1]);
  1176.         return 1;
  1177.     }
  1178.     if(argc >= 3)
  1179.         ifp->trace = htoi(argv[2]);
  1180.  
  1181.     showtrace(ifp);
  1182.     return 0;
  1183. }
  1184. /* Display the trace flags for a particular interface */
  1185. static
  1186. showtrace(ifp)
  1187. register struct interface *ifp;
  1188. {
  1189.     if(ifp == NULLIF)
  1190.         return;
  1191.     printf("%s:",ifp->name);
  1192.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  1193.         if(ifp->trace & IF_TRACE_IN)
  1194.             printf(" input");
  1195.         if(ifp->trace & IF_TRACE_OUT)
  1196.             printf(" output");
  1197.  
  1198.         if(ifp->trace & IF_TRACE_HEX)
  1199.             printf(" (Hex/ASCII dump)");
  1200.         else if(ifp->trace & IF_TRACE_ASCII)
  1201.             printf(" (ASCII dump)");
  1202.         else
  1203.             printf(" (headers only)");
  1204.         printf("\n");
  1205.     } else
  1206.         printf(" tracing off\n");
  1207.     fflush(stdout);
  1208. }
  1209. #endif
  1210.  
  1211. #if    ((!defined(MSDOS) && !defined(ATARI_ST)) || defined(PC9801))
  1212. static
  1213. int
  1214. doescape(argc,argv)
  1215. int argc;
  1216. char *argv[];
  1217. {
  1218.     if(argc < 2)
  1219.         printf("0x%x\n",escape);
  1220.     else 
  1221.         escape = *argv[1];
  1222.     return 0;
  1223. }
  1224. #endif    /* MSDOS */
  1225. /*ARGSUSED*/
  1226. static
  1227. doremote(argc,argv)
  1228. int argc;
  1229. char *argv[];
  1230. {
  1231.     struct socket fsock,lsock;
  1232.     struct mbuf *bp;
  1233.  
  1234.     lsock.address = ip_addr;
  1235.     fsock.address = resolve(argv[1]);
  1236.     lsock.port = fsock.port = atoi(argv[2]);
  1237.     bp = alloc_mbuf(1);
  1238.     if(strcmp(argv[3],"reset") == 0){
  1239.         *bp->data = SYS_RESET;
  1240.     } else if(strcmp(argv[3],"exit") == 0){
  1241.         *bp->data = SYS_EXIT;
  1242.     } else {
  1243.         printf("Unknown command %s\n",argv[3]);
  1244.         return 1;
  1245.     }
  1246.     bp->cnt = 1;
  1247.     send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  1248.     return 0;
  1249. }
  1250.